home *** CD-ROM | disk | FTP | other *** search
- From: Jeff Lee <talcott!seismo!gatech!jeff>
- Subject: Georgia Tech 'se' screen editor (Part 3 of 8)
- Keywords: Software Tools, Yet Another Screen Editor, Both BSD and USG
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 84
- Submitted by: Jeff Lee <seismo!gatech!jeff>
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # docmd1.c
- # docmd2.c
- # misc.c
- # This archive created: Tue Apr 29 11:01:33 1986
- export PATH; PATH=/bin:/usr/bin:$PATH
- echo shar: "extracting 'docmd1.c'" '(29123 characters)'
- if test -f 'docmd1.c'
- then
- echo shar: "will not over-write existing file 'docmd1.c'"
- else
- cat << \SHAR_EOF > 'docmd1.c'
- /*
- ** docmd1.c
- **
- ** main command processor. routines for individual commands
- */
-
- #include "se.h"
- #include "extern.h"
-
- /* static data definitions -- variables only needed in this file */
- static char Tlpat[MAXPAT] = ""; /* saved character list for y/t command */
- static char Tabstr[MAXLINE] = ""; /* string representation of tab stops */
- static char Ddir = FORWARD; /* delete direction */
- static int Compress; /* compress/expand tabs on read/write */
-
- /* docmd --- handle all commands except globals */
-
- int docmd (lin, i, glob, status)
- char lin[];
- int i, glob, *status;
- {
- char file[MAXLINE], sub[MAXPAT];
- char kname;
- int gflag, line3, pflag, flag, fflag, junk, allbut, tflag;
- int append (), ckchar (), ckp (), ckupd (), copy ();
- int delete (), domark (), doopt (), doprnt (), doread ();
- int doshell ();
- int dotlit (), doundo (), dowrit (), getfn (), getkn ();
- int getone (), getrange (), getrhs (), getstr (), inject ();
- int join (), makset (), move (), nextln (), optpat ();
- int prevln (), substr (), draw_box ();
- char *expand_env ();
-
-
- *status = ERR;
- if (intrpt ()) /* catch a pending interrupt */
- return (*status);
-
- switch (lin[i]) {
- case APPENDCOM:
- case UCAPPENDCOM:
- if (lin[i + 1] == '\n' || lin[i + 1] == ':')
- {
- defalt (Curln, Curln);
- if (lin[i + 1] == '\n')
- {
- /* avoid updating with inline insertion */
- adjust_window (Line1, Line2);
- updscreen ();
- }
- *status = append (Line2, &lin[i + 1]);
- }
- break;
-
- case PRINTCUR:
- if (lin[i + 1] == '\n')
- {
- defalt (Curln, Curln);
- saynum (Line2);
- *status = OK;
- }
- break;
-
- case OVERLAYCOM:
- case UCOVERLAYCOM:
- defalt (Curln, Curln);
- if (lin[i + 1] == '\n')
- overlay (status);
- break;
-
- case CHANGE:
- case UCCHANGE:
- defalt (Curln, Curln);
- if (Line1 <= 0)
- Errcode = EORANGE;
- else if (lin[i + 1] == '\n' || lin[i + 1] == ':')
- {
- if (lin[i + 1] == '\n')
- {
- /* avoid updating with inline insertion */
- adjust_window (Line2, Line2);
- updscreen ();
- }
- First_affected = min (First_affected, Line1);
- if (lin[i + 1] == '\n')
- warn_deleted (Line1, Line2);
- *status = append (Line2, &lin[i + 1]);
- if (*status != ERR)
- {
- line3 = Curln;
- delete (Line1, Line2, status);
- Curln = line3 - (Line2 - Line1 + 1);
- /* adjust for deleted lines */
- }
- }
- break;
-
- case DELCOM:
- case UCDELCOM:
- if (ckp (lin, i + 1, &pflag, status) == OK)
- {
- defalt (Curln, Curln);
- if (delete (Line1, Line2, status) == OK
- && Ddir == FORWARD
- && nextln (Curln) != 0)
- Curln = nextln (Curln);
- }
- break;
-
- case INSERT:
- case UCINSERT:
- defalt (Curln, Curln);
- if (Line1 <= 0)
- Errcode = EORANGE;
- else if (lin[i + 1] == '\n' || lin[i + 1] == ':')
- {
- if (lin[i + 1] == '\n')
- {
- /* avoid updating with inline insertion */
- adjust_window (Line1, Line2);
- updscreen ();
- }
- *status = append (prevln (Line2), &lin[i + 1]);
- }
- break;
-
- case MOVECOM:
- case UCMOVECOM:
- i++;
- if (getone (lin, &i, &line3, status) == EOF)
- *status = ERR;
- if (*status == OK && ckp (lin, i, &pflag, status) == OK)
- {
- defalt (Curln, Curln);
- *status = move (line3);
- }
- break;
-
- case COPYCOM:
- case UCCOPYCOM:
- if (! Unix_mode)
- goto translit; /* SWT uses 't' for translit */
- /* else
- fall through and act normally */
- docopy:
- i++;
- if (getone (lin, &i, &line3, status) == EOF)
- *status = ERR;
- if (*status == OK && ckp (lin, i, &pflag, status) == OK)
- {
- defalt (Curln, Curln);
- *status = copy (line3);
- }
- break;
-
- case SUBSTITUTE:
- case UCSUBSTITUTE:
- i++;
- if (lin[i] == '\n')
- {
- /* turn "s\n" into "s//%/\n" */
- lin[i+0] = '/';
- lin[i+1] = '/';
- lin[i+2] = Unix_mode ? '%' : '&';
- lin[i+3] = '/';
- lin[i+4] = '\n';
- lin[i+5] = EOS;
- Peekc = SKIP_RIGHT;
- }
- else
- {
- /* try to handle "s/stuff\n" */
- int j, missing_delim;
-
- missing_delim = YES;
- for (j = i + 1; lin[j] != '\n'; j++)
- if (lin[j] == ESCAPE && lin[j+1] == lin[i])
- j++; /* skip esc, loop continues */
- else if (lin[j] == lin[i])
- {
- missing_delim = NO;
- break; /* for */
- }
-
- if (missing_delim)
- {
- for (; lin[j] != EOS; j++)
- ;
- j--; /* j now at newline */
-
- lin[j] = lin[i]; /* delim */
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- /* rest of routines will continue to fix up */
- }
- }
-
- if (optpat (lin, &i) == OK
- && getrhs (lin, &i, sub, &gflag) == OK
- && ckp (lin, i + 1, &pflag, status) == OK)
- {
- defalt (Curln, Curln);
- *status = subst (sub, gflag, glob);
- }
- break;
-
- case TLITCOM:
- case UCTLITCOM:
- if (! Unix_mode)
- goto docopy; /* SWT uses 'y' for copying */
- /* else
- fall through and act normally */
- translit:
- i++;
- if (lin[i] == '\n')
- {
- /* turn "y\n" into "y//%/\n" */
- lin[i+0] = '/';
- lin[i+1] = '/';
- lin[i+2] = Unix_mode ? '%' : '&';
- lin[i+3] = '/';
- lin[i+4] = '\n';
- lin[i+5] = EOS;
- Peekc = SKIP_RIGHT;
- }
- else
- {
- /* try to handle "y/stuff\n" */
- int j, missing_delim;
-
- missing_delim = YES;
- for (j = i + 1; lin[j] != '\n'; j++)
- if (lin[j] == ESCAPE && lin[j+1] == lin[i])
- j++; /* skip esc, loop continues */
- else if (lin[j] == lin[i])
- {
- missing_delim = NO;
- break; /* for */
- }
-
- if (missing_delim)
- {
- for (; lin[j] != EOS; j++)
- ;
- j--; /* j now at newline */
-
- lin[j] = lin[i]; /* delim */
- lin[++j] = '\n';
- lin[++j] = EOS;
- Peekc = SKIP_RIGHT;
- /* rest of routines will continue to fix up */
- }
- }
-
- if (getrange (lin, &i, Tlpat, MAXPAT, &allbut) == OK
- && makset (lin, &i, sub, MAXPAT) == OK
- && ckp (lin, i + 1, &pflag, status) == OK)
- {
- defalt (Curln, Curln);
- *status = dotlit (sub, allbut);
- }
- break;
-
- case JOINCOM:
- case UCJOINCOM:
- i++;
- if (getstr (lin, &i, sub, MAXPAT) == OK
- && ckp (lin, i + 1, &pflag, status) == OK)
- {
- defalt (prevln (Curln), Curln);
- *status = join (sub);
- }
- break;
-
- case UNDOCOM:
- case UCUNDOCOM:
- i++;
- defalt (Curln, Curln);
- if (ckchar (UCDELCOM, DELCOM, lin, &i, &flag, status) == OK
- && ckp (lin, i, &pflag, status) == OK)
- *status = doundo (flag, status);
- break;
-
- case ENTER:
- case UCENTER:
- i++;
- if (Nlines != 0)
- Errcode = EBADLNR;
- else if (ckupd (lin, &i, ENTER, status) == OK
- && ckchar ('x', 'X', lin, &i, &tflag, status) == OK)
- if (getfn (lin, i - 1, file) == OK)
- {
- strcpy (Savfil, expand_env (file));
- mesg (Savfil, FILE_MSG);
- clrbuf ();
- mkbuf ();
- dfltsopt (file);
- *status = doread (0, file, tflag);
- First_affected = 0;
- Curln = min (1, Lastln);
- Buffer_changed = NO;
- }
- else
- *status = ERR;
- break;
-
- case PRINTFIL:
- case UCPRINTFIL:
- if (Nlines != 0)
- Errcode = EBADLNR;
- else if (getfn (lin, i, file) == OK)
- {
- strcpy (Savfil, expand_env (file));
- mesg (Savfil, FILE_MSG);
- *status = OK;
- }
- break;
-
- case READCOM:
- case UCREADCOM:
- i++;
- if (ckchar ('x', 'X', lin, &i, &tflag, status) == OK)
- if (getfn (lin, i - 1, file) == OK)
- {
- defalt (Curln, Curln);
- *status = doread (Line2, file, tflag);
- }
- break;
-
- case WRITECOM:
- case UCWRITECOM:
- i++;
- flag = NO;
- fflag = NO;
- junk = ckchar ('>', '+', lin, &i, &flag, &junk);
- if (flag == NO)
- junk = ckchar ('!', '!', lin, &i, &fflag, &junk);
- junk = ckchar ('x', 'X', lin, &i, &tflag, &junk);
- if (getfn (lin, i - 1, file) == OK)
- {
- defalt (1, Lastln);
- *status = dowrit (Line1, Line2, file, flag, fflag, tflag);
- }
- break;
-
- case PRINT:
- case UCPRINT:
- if (lin[i + 1] == '\n')
- {
- defalt (1, Topln);
- *status = doprnt (Line1, Line2);
- }
- break;
-
- case PAGECOM:
- defalt (1, min (Lastln, Botrow - Toprow + Topln));
- if (Line1 <= 0)
- Errcode = EORANGE;
- else if (lin[i + 1] == '\n')
- {
- Topln = Line2;
- Curln = Line2;
- First_affected = Line2;
- *status = OK;
- }
- break;
-
- case NAMECOM:
- case UCNAMECOM:
- i++;
- if (getkn (lin, &i, &kname, DEFAULTNAME) != ERR
- && lin[i] == '\n')
- uniquely_name (kname, status);
- break;
-
- case MARKCOM:
- case UCMARKCOM:
- i++;
- if (getkn (lin, &i, &kname, DEFAULTNAME) != ERR
- && lin[i] == '\n')
- {
- defalt (Curln, Curln);
- *status = domark (kname);
- }
- break;
-
- case '\n':
- line3 = nextln (Curln);
- defalt (line3, line3);
- *status = doprnt (Line2, Line2);
- break;
-
- case LOCATECMD:
- case UCLOCATECMD:
- if (lin[i+1] == '\n')
- {
- char *sysname ();
-
- remark (sysname ());
- *status = OK;
- }
- break;
-
- case OPTCOM:
- case UCOPTCOM:
- if (Nlines == 0)
- *status = doopt (lin, &i);
- else
- Errcode = EBADLNR;
- break;
-
- case QUIT:
- case UCQUIT:
- i++;
- if (Nlines != 0)
- Errcode = EBADLNR;
- else if (ckupd (lin, &i, QUIT, status) == OK)
- if (lin[i] == '\n')
- *status = EOF;
- else
- *status = ERR;
- break;
-
- case HELP:
- case UCHELP:
- i++;
- if (Nlines == 0)
- dohelp (lin, &i, status);
- else
- Errcode = EBADLNR;
- break;
-
- case MISCCOM: /* miscellanious features */
- case UCMISCCOM:
- i++;
- switch (lin[i]) {
- case 'b': /* draw box */
- case 'B':
- defalt (Curln, Curln);
- i++;
- *status = draw_box (lin, &i);
- break;
-
- default:
- Errcode = EWHATZAT;
- break;
- }
- break;
-
- case SHELLCOM:
- if (! Unix_mode)
- error ("in docmd: can't happen.");
- shellcom:
- i++;
- defalt (Curln, Curln);
- *status = doshell (lin, &i);
- break;
-
- case '~':
- if (! Unix_mode)
- goto shellcom;
- /* else
- fall through to default
- which will generate an error */
-
- default:
- Errcode = EWHATZAT; /* command not recognized */
- break;
- }
-
- if (*status == OK)
- Probation = NO;
-
- return (*status);
- }
-
-
- /* dohelp --- display documentation about editor */
-
- dohelp (lin, i, status)
- char lin[];
- int *i, *status;
- {
- char filename[MAXLINE];
- char swt_filename[MAXLINE];
- static char helpdir[] = "/usr/local/lib/se_h"; /* help scripts */
- int j;
- FILE *fp, *fopen ();
-
- SKIPBL (lin, *i);
- if (lin[*i] == NEWLINE)
- sprintf (filename, "%s/elp", helpdir);
- else
- {
- /* build filename from text after "h" */
- sprintf (filename, "%s/%s", helpdir, &lin[*i]);
- j = strlen (filename);
- filename[j-1] = EOS; /* lop off newline */
- }
-
- /* map to lower case */
- for (j = 0; filename[j] != EOS; j++)
- if (isupper (filename[j]))
- filename[j] = tolower (filename[j]);
-
- sprintf (swt_filename, "%s_swt", filename);
-
- if (! Unix_mode && access (swt_filename, 4) == 0)
- strcpy (filename, swt_filename);
- /* SWT version of help file exists, use it */
- /* else
- use Unix or normal version of the help file */
-
- *status = OK;
- if ((fp = fopen (filename, "r")) == NULL)
- {
- *status = ERR;
- Errcode = ENOHELP;
- }
- else
- {
- #ifdef u3b2
- /* 3B2 seems to have problems with stdio and malloc... */
- char buf[BUFSIZ];
- setbuf (fp, buf);
- #endif
-
- /* status is OK */
- display_message (fp); /* display the help script */
- fclose (fp);
- }
- }
-
-
- /* doopt --- interpret option command */
-
- int doopt (lin, i)
- char lin[];
- int *i;
- {
- int temp, line, stat;
- char tempstr[4];
- int ret;
- int dosopt ();
- int ctoi ();
-
- (*i)++;
- ret = ERR;
-
- switch (lin[*i]) {
-
- case 'g': /* substitutes in a global can(not) fail */
- case 'G':
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- Globals = ! Globals; /* toggle */
- if (Globals == YES)
- remark ("failed global substitutes continue");
- else
- remark ("failed global substitutes stop");
- }
- break;
-
- case 'h':
- case 'H': /* do/don't use hardware insert/delete */
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- No_hardware = ! No_hardware;
- if (No_hardware == YES)
- remark ("no line insert/delete");
- else
- remark ("line insert/delete");
- }
- break;
-
- case 'k': /* tell user if buffer saved or not */
- case 'K':
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- if (Buffer_changed == YES)
- remark ("not saved");
- else
- remark ("saved");
- }
- break;
-
-
- case 'z': /* suspend the editor process */
- case 'Z':
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- #ifdef BSD
- if (Catching_stops)
- {
- char *getenv ();
-
- /*
- * order the test this way so that it fails
- * immediately in the usual case
- */
- if (getenv ("RSE") != NULL && At_gtics)
- {
- remark ("You may not suspend me");
- break; /* switch */
- }
- else if (Buffer_changed == YES)
- fprintf (stderr, "WARNING: buffer not saved\n");
- kill (getpid(), SIGTSTP);
- /* stop_hdlr() will do all the work for us */
- }
- #else
- remark ("process suspension not available");
- #endif
- }
- break;
-
- case 't': /* set or display tab stops for expanding tabs */
- case 'T':
- ++(*i);
- if (lin[*i] == '\n')
- {
- remark (Tabstr);
- ret = OK;
- }
- else
- {
- ret = settab (&lin[*i]);
- if (ret == OK)
- strcpy (Tabstr, &lin[*i]);
- else /* defaults were set */
- strcpy (Tabstr, "+4");
- }
- break;
-
- case 'w': /* set or display warning column */
- case 'W':
- ++(*i);
- if (lin[*i] == '\n')
- ret = OK;
- else
- {
- temp = ctoi (lin, i);
- if (lin[*i] == '\n')
- if (temp > 0 && temp < MAXLINE - 3)
- {
- ret = OK;
- Warncol = temp;
- }
- else
- Errcode = ENONSENSE;
- }
- if (ret == OK)
- saynum (Warncol);
- break;
-
- case '-': /* fix window in place on screen, or erase it */
- ++(*i);
- if (getnum (lin, i, &line, &stat) == EOF)
- {
- mesg ("", HELP_MSG);
- if (Toprow > 0)
- {
- Topln = max (1, Topln - Toprow);
- Toprow = 0;
- First_affected = Topln;
- }
- ret = OK;
- }
- else if (stat != ERR && lin[*i] == '\n')
- if (Toprow + (line - Topln + 1) < Cmdrow)
- {
- Toprow += line - Topln + 1;
- Topln = line + 1;
- for (temp = 0; temp < Ncols; temp++)
- load ('-', Toprow - 1, temp);
- if (Topln > Lastln)
- adjust_window (1, Lastln);
- if (Curln < Topln)
- Curln = min (Topln, Lastln);
- ret = OK;
- }
- else
- Errcode = EORANGE;
- break;
-
- case 'a': /* toggle absolute line numbering */
- case 'A':
- if (lin[*i + 1] == '\n')
- {
- Absnos = ! Absnos;
- ret = OK;
- }
- break;
-
- case 'c': /* toggle case option */
- case 'C':
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- Invert_case = ! Invert_case;
- if (Rel_a == 'A')
- {
- Rel_a = 'a';
- Rel_z = 'z';
- }
- else
- {
- Rel_a = 'A';
- Rel_z = 'Z';
- }
- }
-
- mesg (Invert_case ? "CASE" : "", CASE_MSG);
- break;
-
- case 'd': /* set or display placement of "." after a delete */
- case 'D':
- if (lin[*i + 1] == '\n')
- {
- if (Ddir == FORWARD)
- remark (">");
- else
- remark ("<");
- ret = OK;
- }
- else if (lin[*i + 2] != '\n')
- Errcode = EODLSSGTR;
- else if (lin[*i + 1] == '>')
- {
- ret = OK;
- Ddir = FORWARD;
- }
- else if (lin[*i + 1] == '<')
- {
- ret = OK;
- Ddir = BACKWARD;
- }
- else
- Errcode = EODLSSGTR;
- break;
-
- case 'v': /* set or display overlay column */
- case 'V':
- ++(*i);
- if (lin[*i] == '\n')
- {
- if (Overlay_col == 0)
- remark ("$");
- else
- saynum (Overlay_col);
- ret = OK;
- }
- else
- {
- if (lin[*i] == '$' && lin[*i + 1] == '\n')
- {
- Overlay_col = 0;
- ret = OK;
- }
- else
- {
- temp = ctoi (lin, i);
- if (lin[*i] == '\n')
- {
- Overlay_col = temp;
- ret = OK;
- }
- else
- Errcode = ENONSENSE;
- }
- }
- break;
-
- case 'u': /* set or display character for unprintable chars */
- case 'U':
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- tempstr[0] = tempstr[2] = '"';
- tempstr[1] = Unprintable;
- tempstr[3] = EOS;
- remark (tempstr);
- }
- else if (lin[*i + 2] == '\n')
- {
- if (lin[*i + 1] < ' ' || lin[*i + 1] >= DEL)
- Errcode = ENONSENSE;
- else
- {
- ret = OK;
- if (Unprintable != lin[*i + 1])
- {
- Unprintable = lin[*i + 1];
- First_affected = Topln;
- }
- }
- }
- break;
-
- case 'l': /* set or display line number display option */
- case 'L':
- if (lin[*i+1] == '\n')
- {
- Nchoise = EOS;
- ret = OK;
- }
- else if (lin[*i + 2] == '\n' &&
- (lin[*i + 1] == CURLINE || lin[*i + 1] == LASTLINE
- || lin[*i + 1] == TOPLINE))
- {
- Nchoise = lin[*i + 1];
- ret = OK;
- }
- else if (lin[*i + 1] == 'm' || lin[*i + 1] == 'M')
- {
- /* set or display the left margin */
- (*i)++;
- if (lin[*i + 1] == '\n')
- {
- saynum (Firstcol + 1);
- ret = OK;
- }
- else
- {
- (*i)++;
- temp = ctoi (lin, i);
- if (lin[*i] == '\n')
- if (temp > 0 && temp < MAXLINE)
- {
- First_affected = Topln;
- Firstcol = temp - 1;
- ret = OK;
- }
- else
- Errcode = ENONSENSE;
- }
- }
- break;
-
- case 'f': /* fortran (ugh, yick, gross) options */
- case 'F':
- if (lin[*i + 1] == '\n')
- ret = dosopt ("f");
- break;
-
- case 's': /* set source options */
- case 'S':
- ret = dosopt (&lin[*i + 1]);
- break;
-
- case 'i': /* set or display indent option */
- case 'I':
- ++(*i);
- if (lin[*i] == '\n')
- ret = OK;
- else if ((lin[*i] == 'a' || lin[*i] == 'A') && lin[*i + 1] == '\n')
- {
- Indent = 0;
- ret = OK;
- }
- else
- {
- temp = ctoi (lin, i);
- if (lin[*i] == '\n')
- if (temp > 0 && temp < MAXLINE - 3)
- {
- ret = OK;
- Indent = temp;
- }
- else
- Errcode = ENONSENSE;
- }
- if (ret == OK)
- if (Indent > 0)
- saynum (Indent);
- else
- remark ("auto");
- break;
-
- case 'm': /* toggle mail notification */
- case 'M':
- if (lin[*i + 1] == '\n')
- {
- Notify = ! Notify; /* toggle notification */
- remark (Notify ? "notify on" : "notify off");
- ret = OK;
- }
- break;
-
- case 'p': /* toggle pattern and command style */
- case 'P': /* if additional letter there, it forces mode */
- ret = OK;
- switch (lin[*i + 1]) {
- case EOS:
- case '\n': /* toggle */
- if (Unix_mode)
- goto no_unix;
- /* currently in Unix mode */
- /* switch to SWT style patterns */
- else
- goto yes_unix;
- /* currently in SWT mode */
- /* switch to Unix style patterns */
-
- break;
-
- case 's': /* force SWT mode */
- case 'S':
- no_unix: Unix_mode = NO;
- BACKSCAN = '\\';
- NOTINCCL = '~';
- XMARK = '!';
- ESCAPE = '@';
- break;
-
- case 'u': /* force UNIX mode */
- case 'U':
- yes_unix: Unix_mode = YES;
- BACKSCAN = '?';
- NOTINCCL = '^';
- XMARK = '~';
- ESCAPE = '\\';
- break;
-
- default:
- Errcode = EOWHAT;
- ret = ERR;
- goto out_of_here;
- }
- set_patterns (Unix_mode);
- mesg (Unix_mode ? "UNIX" : "SWT", MODE_MSG);
- out_of_here:
- break;
-
- case 'x':
- case 'X': /* toggle tab compression */
- if (lin[*i + 1] == '\n')
- {
- ret = OK;
- Compress = ! Compress;
- mesg (Compress ? "XTABS" : "", COMPRESS_MSG);
- }
- break;
-
- case 'y': /* encrypt files */
- case 'Y':
- if (lin[*i + 1] == '\n')
- {
- crypt_toggle:
- ret = OK;
- Crypting = ! Crypting;
- if (Crypting )
- do {
- getkey ();
- if (Key[0] == EOS)
- remark ("Empty keys are not allowed.\n");
- } while (Key[0] == EOS);
- else
- Key[0] = EOS;
- }
- else
- {
- register int j;
-
- ret = OK;
- (*i)++; /* *i was the 'y' */
- while (isspace (lin[*i]) && lin[*i] != '\n')
- (*i)++;
- if (lin[*i] != '\n' && lin[*i] != EOS)
- {
- for (j = 0; lin[*i] != '\n' && lin[*i] != EOS;
- j++, (*i)++)
- Key[j] = lin[*i];
- Key[j] = EOS;
- Crypting = YES;
- }
- else
- goto crypt_toggle;
- }
- mesg (Crypting ? "ENCRYPT" : "", CRYPT_MSG);
- break;
-
- default:
- Errcode = EOWHAT;
-
- }
-
- return (ret);
- }
-
-
- /* domark --- name lines line1 through line2 as kname */
-
- int domark (kname)
- char kname;
- {
- int line;
- int ret;
- register LINEDESC *k;
- LINEDESC *getind ();
-
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- ret = ERR;
- }
- else
- {
- k = getind (Line1);
- for (line = Line1; line <= Line2; line++)
- {
- if (intrpt())
- return (ERR);
- k -> Markname = kname;
- k = NEXTLINE(k);
- }
- ret = OK;
- }
- return (ret);
- }
-
-
- /* doprnt --- set curln, locate window */
-
- int doprnt (from, to)
- int from, to;
- {
-
- if (from <= 0)
- {
- Errcode = EORANGE;
- return (ERR);
- }
-
- adjust_window (from, to);
- Curln = to;
- return (OK);
- }
-
-
- /* doread --- read "file" after "line" */
-
- int doread (line, file, tflag)
- int line;
- char *file;
- int tflag;
- {
- register int count, len, i;
- int ret;
- int strlen ();
- FILE *fd;
- FILE *fopen (), *crypt_open ();
- char lin1[MAXLINE], lin2[MAXLINE];
- char *fgets ();
- register LINEDESC *ptr;
- LINEDESC *sp_inject ();
- LINEDESC *getind ();
- char *expand_env ();
-
- file = expand_env (file); /* expand $HOME, etc. */
-
- if (Savfil[0] == EOS)
- {
- strcpy (Savfil, file);
- mesg (Savfil, FILE_MSG);
- }
-
- if (Crypting)
- fd = crypt_open (file, "r");
- else
- fd = fopen (file, "r");
-
- if (fd == NULL)
- {
- ret = ERR;
- Errcode = ECANTREAD;
- }
- else
- {
- First_affected = min (First_affected, line + 1);
- ptr = getind (line);
- ret = OK;
- #ifndef OLD_SCRATCH
- Curln = line;
- #endif
- remark ("reading");
- for (count = 0; fgets (lin1, MAXLINE, fd) != NULL; count++)
- {
- if (intrpt ())
- {
- ret = ERR;
- break;
- }
- if (Compress == NO && tflag == NO)
- ptr = sp_inject (lin1, strlen (lin1), ptr);
- else
- {
- len = 0;
- for (i = 0; lin1[i] != EOS && len < MAXLINE - 1; i++)
- if (lin1[i] != '\t')
- lin2[len++] = lin1[i];
- else
- do
- lin2[len++] = ' ';
- while (len % 8 != 0
- && len < MAXLINE - 1);
- lin2[len] = EOS;
- if (len >= MAXLINE)
- {
- ret = ERR;
- Errcode = ETRUNC;
- }
- ptr = sp_inject (lin2, len, ptr);
- }
- if (ptr == NOMORE)
- {
- ret = ERR;
- break;
- }
- }
- if (Crypting)
- crypt_close (fd);
- else
- fclose (fd);
- saynum (count);
- Curln = line + count;
- svins (line, count);
- }
-
- return (ret);
- }
-
-
- /* dosopt --- set source language-related options */
-
- int dosopt (lin)
- char lin[];
- {
- char lang[8];
- int i;
- int strbsr ();
- static struct {
- char *txt;
- int val;
- } ltxt[] = {
- "", 1,
- "as", 2,
- "c", 3,
- "d", 1,
- "data", 1,
- "f", 4,
- "h", 3,
- "n", 1,
- "nr", 1,
- "nroff",1,
- "p", 3,
- "r", 3,
- "s", 2,
- };
-
- i = 0;
- getwrd (lin, &i, lang, 8);
-
- strmap (lang, 'a');
-
- i = strbsr ((char *)ltxt, sizeof (ltxt), sizeof (ltxt[0]), lang);
- if (i == EOF)
- {
- Errcode = ENOLANG;
- return (ERR);
- }
-
- switch (ltxt[i].val) {
- case 1:
- Warncol = 74;
- Rel_a = 'A';
- Rel_z = 'Z';
- Invert_case = NO;
- strcpy (Tabstr, "+4");
- settab (Tabstr);
- Compress = NO;
- break;
-
- case 3:
- Warncol = 74;
- Rel_a = 'A';
- Rel_z = 'Z';
- Invert_case = NO;
- strcpy (Tabstr, "+8");
- settab (Tabstr);
- Compress = YES;
- break;
- case 4:
- Warncol = 72;
- Rel_a = 'A';
- Rel_z = 'Z';
- Invert_case = NO;
- strcpy (Tabstr, "7+3");
- settab (Tabstr);
- Compress = YES;
- break;
-
- case 2:
- Warncol = 72;
- Rel_a = 'A';
- Rel_z = 'Z';
- Invert_case = NO;
- strcpy (Tabstr, "17+8");
- settab (Tabstr);
- Compress = YES;
- break;
- }
-
- mesg (Invert_case == YES ? "CASE" : "", CASE_MSG);
- mesg (Compress == YES ? "XTABS" : "", COMPRESS_MSG);
-
- return (OK);
- }
-
-
- /* dotlit --- transliterate characters */
-
- int dotlit (sub, allbut)
- char sub[];
- int allbut;
- {
- char new[MAXLINE];
- char kname;
- int collap, x, i, j, line, lastsub, status;
- int ret;
- LINEDESC *inx;
- LINEDESC *gettxt (), *getind ();
-
- ret = ERR;
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- return (ret);
- }
-
- if (First_affected > Line1)
- First_affected = Line1;
-
- lastsub = strlen (sub) - 1;
- if ((strlen (Tlpat) - 1) > lastsub || allbut == YES)
- collap = YES;
- else
- collap = NO;
-
- for (line = Line1; line <= Line2; line++)
- {
- if (intrpt ()) /* check for interrupts */
- return (ERR);
-
- inx = gettxt (line); /* get text of line into txt, return index */
- j = 0;
- for (i = 0; Txt[i] != EOS && Txt[i] != '\n'; i++)
- {
- x = xindex (Tlpat, Txt[i], allbut, lastsub);
- if (collap == YES && x >= lastsub && lastsub >= 0) /* collapse */
- {
- new[j] = sub[lastsub];
- j++;
- for (i++; Txt[i] != EOS && Txt[i] != '\n'; i++)
- {
- x = xindex (Tlpat, Txt[i], allbut, lastsub);
- if (x < lastsub)
- break;
- }
- }
- if (Txt[i] == EOS || Txt[i] == '\n')
- break;
- if (x >= 0 && lastsub >= 0) /* transliterate */
- {
- new[j] = sub[x];
- j++;
- }
- else if (x < 0) /* copy */
- {
- new[j] = Txt[i];
- j++;
- }
- /* else
- delete */
- }
-
- if (Txt[i] == '\n') /* add a newline, if necessary */
- {
- new[j] = '\n';
- j++;
- }
- new[j] = EOS; /* add the EOS */
-
- kname = inx -> Markname; /* save the markname */
- delete (line, line, &status);
- ret = inject (new);
- if (ret == ERR)
- break;
- inx = getind (Curln);
- inx -> Markname = kname; /* set markname */
- ret = OK;
- Buffer_changed = YES;
- }
-
- return (ret);
- }
-
- /* doundo --- restore last set of lines deleted */
-
- int doundo (dflg, status)
- int dflg;
- int *status;
- {
- LINEDESC *l1, *l2, *k1, *k2;
- LINEDESC *getind ();
- int oldcnt;
- int nextln (), prevln ();
-
- *status = ERR;
- if (dflg == NO && Line1 <= 0)
- Errcode = EORANGE;
- else if (Limbo == NOMORE)
- Errcode = ENOLIMBO;
- else if (Line1 > Line2)
- Errcode = EBACKWARD;
- else if (Line2 > Lastln)
- Errcode = ELINE2;
- else
- {
- *status = OK;
- Curln = Line2;
- #ifdef OLD_SCRATCH
- k1 = getind (Line2);
- k2 = getind (nextln (Line2));
- l1 = Limbo;
- l2 = l1 -> Prevline;
- relink (k1, l1, l2, k2);
- relink (l2, k2, k1, l1);
- #else
- blkmove (Limbo - Buf, MAXBUF - 1, Line2);
- #endif
- svins (Line2, Limcnt);
- oldcnt = Limcnt;
- Limcnt = 0;
- Limbo = NOMORE;
- Lastln += oldcnt;
- if (dflg == NO)
- delete (Line1, Line2, status);
- Curln += oldcnt;
- if (First_affected > Line1)
- First_affected = Line1;
- }
-
- return (*status);
- }
-
- /* dowrit --- write "from" through "to" into file */
-
- int dowrit (from, to, file, aflag, fflag, tflag)
- int from, to, aflag, fflag, tflag;
- char *file;
- {
- FILE *fd;
- FILE *fopen (), *crypt_open ();
- register int line, ret, i, j;
- int strcmp (), access ();
- char tabs[MAXLINE];
- register LINEDESC *k;
- LINEDESC *getind ();
- char *expand_env ();
-
- ret = ERR;
- if (from <= 0)
- Errcode = EORANGE;
-
- else
- {
- file = expand_env (file); /* expand $HOME, etc. */
-
- if (aflag == YES)
- {
- if (Crypting)
- fd = crypt_open (file, "a");
- else
- fd = fopen (file, "a");
- }
- else if (strcmp (file, Savfil) == 0 || fflag == YES
- || Probation == WRITECOM || access (file, 0) == -1)
- {
- if (Crypting)
- fd = crypt_open (file, "w");
- else
- fd = fopen (file, "w");
- }
- else
- {
- Errcode = EFEXISTS;
- Probation = WRITECOM;
- return (ret);
- }
- if (fd == NULL)
- Errcode = ECANTWRITE;
- else
- {
- ret = OK;
- remark ("writing");
- k = getind (from);
- for (line = from; line <= to; line++)
- {
- if (intrpt ())
- return (ERR);
- gtxt (k);
- if (Compress == NO && tflag == NO)
- fputs (Txt, fd);
- else
- {
- for (i = 0; Txt[i] == ' '; i++)
- ;
- for (j = 0; j < i / 8; j++)
- tabs[j] = '\t';
- tabs[j] = EOS;
- fputs (tabs, fd);
- fputs (&Txt[j * 8], fd);
- }
- k = NEXTLINE(k);
- }
- if (Crypting)
- crypt_close (fd);
- else
- fclose (fd);
- sync (); /* just in case the system crashes */
- saynum (line - from);
- if (from == 1 && line - 1 == Lastln)
- Buffer_changed = NO;
- }
- }
- return (ret);
- }
-
- /* expand_env --- expand environment variables in file names */
-
- char *expand_env (file)
- register char *file;
- {
- register int i, j, k; /* indices */
- char *getenv ();
- char var[MAXLINE]; /* variable name */
- char *val; /* value of environment variable */
- static char buf[MAXLINE * 2]; /* expanded file name, static to not go away */
-
-
- i = j = k = 0;
- while (file[i] != EOS)
- {
- if (file[i] == ESCAPE)
- {
- if (file[i+1] == '$')
- {
- buf[j++] = file[++i]; /* the actual $ */
- i++; /* for next time around the loop */
- }
- else
- buf[j++] = file[i++]; /* the \ */
- }
- else if (file[i] != '$') /* normal char */
- buf[j++] = file[i++];
- else /* environment var */
- {
- i++; /* skip $ */
- k = 0;
- while (file[i] != '/' && file[i] != EOS)
- var[k++] = file[i++]; /* get var name */
- var[k] = EOS;
-
- if ((val = getenv (var)) != NULL)
- for (k = 0; val[k] != EOS; k++)
- buf[j++] = val[k];
- /* copy val into file name */
- /* else
- var not in enviroment; leave file
- name alone, multiple slashes are legal */
- }
- }
- buf[j] = EOS;
-
- return (buf);
- }
-
- /* crypt_open -- run files through crypt */
-
- FILE *crypt_open (file, mode)
- char *file, *mode;
- {
- char buf[MAXLINE];
- FILE *fp, *popen ();
-
- if (! Crypting)
- return (NULL);
-
- while (Key[0] == EOS)
- {
- getkey ();
- if (Key[0] == EOS)
- printf ("The key must be non-empty!\n");
- }
-
- switch (mode[0]) {
- case 'r':
- sprintf (buf, "crypt %s < %s", Key, file);
- fp = popen (buf, "r");
- return (fp); /* caller checks for NULL or not */
- break;
-
- case 'w':
- sprintf (buf, "crypt %s > %s", Key, file);
- fp = popen (buf, "w");
- return (fp); /* caller checks for NULL or not */
- break;
-
- case 'a':
- sprintf (buf, "crypt %s >> %s", Key, file);
- fp = popen (buf, "w");
- return (fp); /* caller checks for NULL or not */
- break;
-
- default:
- return (NULL);
- }
- }
-
- crypt_close (fp)
- FILE *fp;
- {
- pclose (fp);
- }
-
- /* getkey -- get an encryption key from the user */
-
- #define repeat do
- #define until(cond) while(!(cond))
-
- getkey ()
- {
- char *getpass (); /* get input w/out echoing on screen */
-
- clrscreen (); /* does NOT wipe out Screen_image */
- tflush ();
-
- ttynormal ();
-
- repeat
- {
- strcpy (Key, getpass ("Enter encryption key: "));
- if (strcmp (Key, getpass ("Again: ")) != 0)
- {
- Key[0] = EOS;
- fprintf (stderr, "didn't work. try again.\n");
- }
- /* else
- all ok */
- } until (Key[0] != EOS);
-
- ttyedit ();
-
- restore_screen ();
- }
- SHAR_EOF
- fi
- echo shar: "extracting 'docmd2.c'" '(18236 characters)'
- if test -f 'docmd2.c'
- then
- echo shar: "will not over-write existing file 'docmd2.c'"
- else
- cat << \SHAR_EOF > 'docmd2.c'
- /*
- ** docmd2.c
- **
- ** routines to actually execute commands
- */
-
- #include "se.h"
- #include "extern.h"
-
-
- /* append --- append lines after "line" */
-
- append (line, str)
- int line;
- char str[];
- {
- char lin[MAXLINE];
- char term;
- int ret;
- int len, i, dpos, dotseen;
- int inject ();
-
- Curln = line;
-
- if (str[0] == ':') /* text to be added is in the command line */
- ret = inject (&str[1]);
- else
- {
- Cmdrow = Toprow + (Curln - Topln) + 1; /* 1 below Curln */
- lin[0] = EOS;
- if (Indent > 0 || line <= 0)
- len = max (0, Indent - 1);
- else /* do auto indent */
- {
- LINEDESC *k, *gettxt ();
- k = gettxt (line);
- for (len = 0; Txt[len] == ' '; len++)
- ;
- }
- dpos = len; /* position for terminating '.' */
-
- for (ret = NOSTATUS; ret == NOSTATUS; )
- {
- if (! hwinsdel()) /* do it the old, slow way */
- {
- if (Cmdrow > Botrow)
- {
- Cmdrow = Toprow + 1;
- cprow (Botrow, Toprow);
- adjust_window (Curln, Curln);
- if (First_affected > Topln)
- First_affected = Topln;
- }
- clrrow (Cmdrow);
- if (Cmdrow < Botrow)
- clrrow (Cmdrow + 1);
- }
- else /* try to be smart about it */
- {
- if (Cmdrow > Botrow)
- {
- Cmdrow--;
- dellines (Toprow, 1);
- inslines (Cmdrow, 1);
- Topln++;
- }
- else
- {
- dellines (Botrow, 1);
- inslines (Cmdrow, 1);
- }
- }
- prompt ("apd>");
- do
- getcmd (lin, Firstcol, &len, &term);
- while (term == CURSOR_UP || term == CURSOR_DOWN
- || term == CURSOR_SAME);
-
- dotseen = 0;
- if (lin[0] == '.' && lin[1] == '\n' && lin[2] == EOS)
- dotseen = 1;
- for (i = 0; i < dpos && lin[i] == ' '; i++)
- ;
- if (i == dpos && lin[dpos] == '.' && lin[dpos + 1] == '\n'
- && lin[dpos+2] == EOS)
- dotseen = 1;
-
- if (dotseen)
- {
- if (hwinsdel())
- {
- dellines (Cmdrow, 1);
- inslines (Botrow, 1);
- }
- ret = OK;
- }
- else if (inject (lin) == ERR)
- ret = ERR;
- else /* inject occured */
- prompt (""); /* erase prompt */
- Cmdrow++;
- if (term != FUNNY)
- {
- if (Indent > 0)
- len = Indent - 1;
- else /* do auto indent */
- for (len = 0; lin[len] == ' '; len++)
- ;
- dpos = len;
- lin[0] = EOS;
- }
- }
- Cmdrow = Botrow + 1;
- if (hwinsdel()) /* since we take control */
- { /* of the screen, we're sure */
- Sctop = Topln; /* it's still OK */
-
- for (i = 0; i < Sclen; i++)
- Scline[i] = Sctop + i <= Lastln ? i : -1;
- }
- }
- if (Curln == 0 && Lastln > 0) /* for 0a or 1i followed by "." */
- Curln = 1;
- if (First_affected > line)
- First_affected = line;
-
- tflush ();
- return (ret);
- }
-
- /* copy --- copy line1 through line2 after line3 */
-
- int copy (line3)
- int line3;
- {
- register int i;
- int ret;
- register LINEDESC *ptr3, *after3, *k;
- LINEDESC *getind ();
-
- ret = ERR;
-
- #ifdef OLD_SCRATCH
- ptr3 = getind (line3);
- after3 = ptr3 -> Nextline;
- #endif
-
- if (Line1 <= 0)
- Errcode = EORANGE;
- else
- {
- ret = OK;
- Curln = line3;
- k = getind (Line1);
- for (i = Line1; i <= Line2; i++)
- {
- gtxt (k);
- if (inject (Txt) == ERR || intrpt ())
- {
- ret = ERR;
- break;
- }
- #ifdef OLD_SCRATCH
- if (k == ptr3) /* make sure we don't copy stuff */
- k = after3; /* that's already been copied */
- else
- k = k -> Nextline;
- #else
- if (Line1 < line3)
- k++;
- else
- k += 2;
- /*
- * inject calls blkmove, which will shift the
- * lines down one in the array, so we add two
- * instead of one to get to the next line.
- */
- #endif
- }
- First_affected = min (First_affected, line3 + 1);
- }
- return (ret);
- }
-
-
- /* delete --- delete lines from through to */
-
- int delete (from, to, status)
- int from, to, *status;
- {
- int nextln (), prevln ();
- LINEDESC *k1, *k2, *j1, *j2, *l1;
- LINEDESC *getind ();
-
- if (from <= 0) /* can't delete line 0 */
- {
- *status = ERR;
- Errcode = EORANGE;
- }
- else
- {
- if (First_affected > from)
- First_affected = from;
- #ifdef OLD_SCRATCH
- k1 = getind (prevln (from));
- j1 = k1 -> Nextline;
- j2 = getind (to);
- k2 = j2 -> Nextline;
- relink (k1, k2, k1, k2); /* close chain around deletion */
- #else
- blkmove (from, to, MAXBUF - 1); /* stick at end of buffer */
- #endif
-
- Lastln -= to - from + 1; /* adjust number of last line */
- Curln = prevln (from);
-
- #ifdef OLD_SCRATCH
- if (Limbo != NOMORE) /* discard lines in limbo */
- {
- l1 = Limbo -> Prevline;
- Limbo -> Prevline = Free;
- Free = l1;
- }
- #endif
-
- Lost_lines += Limcnt;
- Limcnt = to - from + 1; /* number of lines "deleted" */
-
- #ifdef OLD_SCRATCH
- Limbo = j1; /* put what we just deleted in limbo */
- relink (j2, j1, j2, j1); /* close the ring */
- #else
- /* point at first deleted */
- Limbo = &Buf[MAXBUF - (to - from + 1)];
- #endif
- *status = OK;
- svdel (from, to - from + 1);
- Buffer_changed = YES;
- }
-
- return (*status);
- }
-
-
- /* join --- join a group of lines into a single line */
-
- int join (sub)
- char sub[];
- {
- char new[MAXLINE];
- register int l, line, sublen;
- int ret;
- int inject (), delete (), prevln (), strlen ();
- register LINEDESC *k;
- LINEDESC *getind ();
-
- ret = OK;
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- return (ERR);
- }
-
- sublen = strlen (sub) + 1; /* length of separator & EOS */
- line = Line1;
- k = getind (line);
- gtxt (k);
- move_ (Txt, new, (int) k -> Lineleng); /* move in first chunk */
- l = k -> Lineleng;
-
- for (line++; line <= Line2; line++)
- {
- if (intrpt ())
- return (ERR);
- if (new[l - 2] == '\n') /* zap the NEWLINE */
- l--;
- k = NEXTLINE(k); /* get the next line */
- gtxt (k);
- if (l + sublen - 1 + k -> Lineleng - 1 > MAXLINE) /* won't fit */
- {
- Errcode = E2LONG;
- return (ERR);
- }
- move_ (sub, &new[l - 1], sublen); /* insert separator string */
- l += sublen - 1;
- move_ (Txt, &new[l - 1], (int) k -> Lineleng); /* move next line */
- l += k -> Lineleng - 1;
- }
- Curln = Line2; /* all this will replace line1 through line2 */
- ret = inject (new); /* inject the new line */
- if (ret == OK)
- ret = delete (Line1, Line2, &ret); /* delete old lines */
- Curln++;
-
- if (First_affected > Curln)
- First_affected = Curln;
-
- return (ret);
- }
-
-
- /* move --- move line1 through line2 after line3 */
-
- int move (line3)
- int line3;
- {
- int nextln (), prevln ();
- LINEDESC *k0, *k1, *k2, *k3, *k4, *k5;
- LINEDESC *getind ();
-
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- return (ERR);
- }
-
- if (Line1 <= line3 && line3 <= Line2)
- {
- Errcode = EINSIDEOUT;
- return (ERR);
- }
-
- #ifdef OLD_SCRATCH
- k0 = getind (prevln (Line1));
- k1 = k0 -> Nextline;
- k2 = getind (Line2);
- k3 = k2 -> Nextline;
- relink (k0, k3, k0, k3);
- #else
- blkmove (Line1, Line2, line3);
- #endif
-
- if (line3 > Line1)
- {
- Curln = line3;
- #ifdef OLD_SCRATCH
- line3 -= Line2 - Line1 + 1;
- #endif
- }
- else
- Curln = line3 + (Line2 - Line1 + 1);
-
- #ifdef OLD_SCRATCH
- k4 = getind (line3);
- k5 = k4 -> Nextline;
- relink (k4, k1, k2, k5);
- relink (k2, k5, k4, k1);
- #endif
-
- Buffer_changed = YES;
- First_affected = min (First_affected, min (Line1, line3));
-
- return (OK);
- }
-
- /* overlay --- let user edit lines directly */
-
- overlay (status)
- int *status;
- {
- char savtxt[MAXLINE], term, kname;
- static char empty[] = "\n";
- int lng, vcol, lcurln, scurln;
- int inject (), nextln (), prevln (), strcmp ();
- LINEDESC *indx;
- LINEDESC *getind (), *gettxt ();
-
- *status = OK;
- if (Line1 == 0)
- {
- Curln = 0;
- *status = inject (empty);
- if (*status == ERR)
- return;
- First_affected = 1;
- Line1 = 1;
- Line2++;
- }
-
- for (lcurln = Line1; lcurln <= Line2; lcurln++)
- {
- Curln = lcurln;
- vcol = Overlay_col - 1;
- do {
- adjust_window (Curln, Curln);
- updscreen ();
- Cmdrow = Curln - Topln + Toprow;
- indx = gettxt (Curln);
- lng = indx -> Lineleng;
- if (Txt[lng - 2] == '\n') /* clobber newline */
- lng--;
- if (vcol < 0)
- vcol = lng - 1;
- while (lng - 1 < vcol)
- {
- Txt[lng - 1] = ' ';
- lng++;
- }
- Txt[lng - 1] = '\n';
- Txt[lng] = EOS;
- move_ (Txt, savtxt, lng + 1); /* make a copy of the line */
- getcmd (Txt, Firstcol, &vcol, &term);
- if (term == FUNNY)
- {
- if (First_affected > Curln)
- First_affected = Curln;
- Cmdrow = Botrow + 1;
- return;
- }
- if (strcmp (Txt, savtxt) != 0) /* was line changed? */
- {
- kname = indx -> Markname;
- delete (Curln, Curln, status);
- scurln = Curln;
- if (*status == OK)
- *status = inject (Txt);
- if (*status == ERR)
- {
- Cmdrow = Botrow + 1;
- return;
- }
- indx = getind (nextln (scurln));
- indx -> Markname = kname;
- }
- else
- { /* in case end-of-line is moved */
- if (First_affected > Curln)
- First_affected = Curln;
- }
- switch (term) {
- case CURSOR_UP:
- if (Curln > 1)
- Curln--;
- else
- Curln = Lastln;
- break;
- case CURSOR_DOWN:
- if (Curln < Lastln)
- Curln++;
- else
- Curln = min (1, Lastln);
- break;
- case CURSOR_SAME:
- vcol = 0;
- break;
- }
- } while (term == CURSOR_UP ||
- term == CURSOR_DOWN ||
- term == CURSOR_SAME);
- }
- Cmdrow = Botrow + 1;
- return;
- }
-
-
- /* subst --- substitute "sub" for occurrences of pattern */
-
- int subst (sub, gflag, glob)
- char sub[];
- int gflag, glob;
- {
- char new[MAXLINE], kname;
- register int line, m, k, lastm;
- int j, junk, status, subbed, ret;
- int tagbeg[10], tagend[10];
- int amatch (), addset (), inject ();
- register LINEDESC *inx;
- LINEDESC *gettxt (), *getind ();
-
- if (Globals && glob)
- ret = OK;
- else
- ret = ERR;
-
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- return (ERR);
- }
-
- /* the following code has been removed for your protection
- index() occasionally grabs newlines out of the character class
- counter in a pattern. for example [0-9] doesn't work due to this
-
- if (index (Pat, '\n') != -1) # never delete NEWLINE
- {
- Errcode = EBADPAT;
- return (ERR);
- }
- */
-
- for (line = Line1; line <= Line2; line++)
- {
- if (intrpt ())
- break;
- j = 0;
- subbed = NO;
- inx = gettxt (line);
- lastm = -1;
- for (k = 0; Txt[k] != EOS; )
- {
- for (m = 1; m <= 9; m++)
- {
- tagbeg[m] = -1;
- tagend[m] = -1;
- }
- if (gflag == YES || subbed == NO)
- m = amatch (Txt, k, Pat, &tagbeg[1], &tagend[1]);
- else
- m = -1;
- if (m > -1 && lastm != m) /* replace matched text */
- {
- subbed = YES;
- tagbeg[0] = k;
- tagend[0] = m;
- catsub (Txt, tagbeg, tagend, sub, new, &j, MAXLINE);
- lastm = m;
- }
- if (m == -1 || m == k) /* no match or null match */
- {
- junk = addset (Txt[k], new, &j, MAXLINE);
- k++;
- }
- else
- k = m; /* skip matched text */
- }
- if (subbed == YES)
- {
- if (addset (EOS, new, &j, MAXLINE) == NO)
- {
- ret = ERR;
- Errcode = E2LONG;
- break;
- }
- kname = inx -> Markname;
- delete (line, line, &status); /* remembers dot */
- ret = inject (new);
- if (First_affected > Curln)
- First_affected = Curln;
- if (ret == ERR)
- break;
- inx = getind (Curln);
- inx -> Markname = kname;
- ret = OK;
- Buffer_changed = YES;
- }
- else /* subbed == NO */
- Errcode = ENOMATCH;
- }
-
- return (ret);
- }
-
-
- /* uniquely_name --- mark-name line; make sure no other line has same name */
-
- uniquely_name (kname, status)
- char kname;
- int *status;
- {
- register int line;
- register LINEDESC *k;
-
- defalt (Curln, Curln);
-
- if (Line1 <= 0)
- {
- *status = ERR;
- Errcode = EORANGE;
- return;
- }
-
- *status = OK;
- line = 0;
- k = Line0;
-
- do {
- line++;
- k = NEXTLINE(k);
- if (line == Line2)
- k -> Markname = kname;
- else if (k -> Markname == kname)
- k -> Markname = DEFAULTNAME;
- } while (line < Lastln);
-
- return;
- }
-
-
- /* draw_box --- draw or erase a box at coordinates in command line */
-
- int draw_box (lin, i)
- char lin[];
- int *i;
- {
- register int left, right, col, len;
- int junk;
- int ctoi (), strcmp (), inject (), delete ();
- register LINEDESC *k;
- LINEDESC *getind (), *gettxt ();
- char text[MAXLINE];
- char kname, ch;
-
- left = ctoi (lin, i);
- if (left <= 0 || left > MAXLINE)
- {
- Errcode = EBADCOL;
- return (ERR);
- }
-
- if (lin[*i] == ',')
- {
- (*i)++;
- SKIPBL (lin, *i);
- right = ctoi (lin, i);
- if (right <= 0 || right >= MAXLINE || left > right)
- {
- Errcode = EBADCOL;
- return (ERR);
- }
- }
- else
- right = left;
-
- SKIPBL (lin, *i);
- if (lin[*i] == '\n')
- ch = ' ';
- else
- ch = lin[(*i)++];
-
- if (lin[*i] != '\n')
- {
- Errcode = EEGARB;
- return (ERR);
- }
-
- if (Line1 <= 0)
- {
- Errcode = EORANGE;
- return (ERR);
- }
-
- for (Curln = Line1; Curln <= Line2; Curln++)
- {
- k = gettxt (Curln);
- len = k -> Lineleng;
- move_ (Txt, text, len);
-
- if (text[len - 2] == '\n')
- col = len - 1;
- else
- col = len;
- while (col <= right)
- {
- text[col - 1] = ' ';
- col++;
- }
- text[col - 1] = '\n';
- text[col] = EOS;
-
- if (Curln == Line1 || Curln == Line2)
- for (col = left; col <= right; col++)
- text[col - 1] = ch;
- else
- {
- text[left - 1] = ch;
- text[right - 1] = ch;
- }
-
- if (strcmp (text, Txt) != 0)
- {
- kname = k -> Markname;
- if (delete (Curln, Curln, &junk) == ERR
- || inject (text) == ERR)
- return (ERR);
- k = getind (Curln);
- k -> Markname = kname;
- Buffer_changed = YES;
- }
- }
-
- Curln = Line1; /* move to top of box */
- if (First_affected > Curln)
- First_affected = Curln;
- adjust_window (Curln, Curln);
- updscreen ();
-
- return (OK);
- }
-
-
- /* dfltsopt --- set the 's' option to the extension on the file name */
-
- dfltsopt (name)
- char name[];
- {
- int i;
- int strlen (), dosopt ();
-
- for (i = strlen (name) - 1; i >= 0; i--)
- if (name[i] == '.')
- {
- dosopt (&name[i + 1]);
- break;
- }
- if (i < 0)
- dosopt ("");
- }
-
-
-
- /* doshell --- escape to the Shell to run one or more Unix commands */
-
- /*
- ** emulate vi: if running just a shell, redraw the screen as
- ** soon as the shell exits. if running a program, let the user
- ** redraw the screen when he/she is ready.
- **
- ** also emulate USG Unix 5.0 ed: a ! as the first character is
- ** replaced by the previous shell command; an unescaped % is replaced
- ** by the saved file name. The expanded command is echoed.
- **
- ** If running at ICS school at Tech, and RSE is in the environment, don't
- ** allow forking, since it's called by a mail-only user.
- */
-
- #ifdef BSD
- #define DEFAULT_PATH "/bin/csh"
- #define DEF_SHELL "csh"
- #else
- #define DEFAULT_PATH "/bin/sh"
- #define DEF_SHELL "sh"
- #endif
-
- int doshell (lin, pi)
- char lin[];
- int *pi;
- {
- int forkstatus, childstatus;
- int (*save_quit)(), (*save_int)();
- int int_hdlr ();
- int (*signal())();
- int i, auto_redraw;
- char *path, *name, *p, *getenv ();
- char new_command[MAXLINE];
- int j, k;
- static char sav_com[MAXLINE] = "";
- int expanded = NO;
-
- if (At_gtics && getenv ("RSE") != NULL) /* yes in environment */
- {
- remark ("You may not run the shell");
- return OK; /* will wipe out command line */
- }
-
- if (Nlines == 0) /* use normal 'ed' behavior */
- {
- tflush (); /* flush out the terminal output */
- position_cursor (Nrows - 1, 0); /* bottom left corner */
-
- if ((p = getenv ("SHELL")) == NULL || strcmp (p, DEFAULT_PATH) == 0)
- {
- path = DEFAULT_PATH;
- name = DEF_SHELL; /* default */
- }
- #ifdef BSD
- /* on Berkeley systems, check the other shell */
- else if (strcmp (p, "/bin/sh") == 0)
- {
- path = "/bin/sh";
- name = "sh";
- }
- #endif
- else
- {
- if (p[0] == '/') /* full pathname there */
- {
- /* work backwards to find just name */
- path = p;
- i = strlen (p);
- while (p[i] != '/')
- i--;
- i++; /* skip '/' */
- name = &p[i];
- }
- else
- {
- char buf[MAXLINE];
-
- sprintf (buf, "unknown shell, using %s",
- DEF_SHELL);
- remark (buf);
- path = DEFAULT_PATH;
- name = DEF_SHELL;
- }
- }
-
- auto_redraw = (lin[*pi] == '\n') ? YES : NO;
-
- /* build command, checking for leading !, and % anywhere */
- if (lin[*pi] == '!')
- {
- if (sav_com[0] != EOS)
- {
- for (j = 0; sav_com[j] != EOS; j++)
- new_command[j] = sav_com[j];
- if (new_command[j-1] == '\n')
- j--;
- (*pi)++;
- expanded = YES;
- }
- else
- {
- Errcode = ENOCMD;
- return (ERR);
- }
- }
- else
- j = 0;
-
- for (i = *pi; lin[i] != EOS; i++)
- {
- if (lin[i] == ESCAPE)
- {
- if (lin[i+1] != '%')
- {
- new_command[j++] = ESCAPE;
- new_command[j++] = lin[++i];
- }
- else
- new_command[j++] = lin[++i];
- }
- else if (lin[i] == '%')
- {
- for (k = 0; Savfil[k] != EOS; k++)
- new_command[j++] = Savfil[k];
- expanded = YES;
- }
- else
- new_command[j++] = lin[i];
- }
-
- if (new_command[j-1] == '\n')
- j--;
- new_command[j] = EOS;
-
- strcpy (sav_com, new_command); /* save it */
-
- ttynormal ();
- #ifndef HARD_TERMS
- t_exit ();
- #endif
- write (1, "\n\n", 2); /* clear out a line */
-
- forkstatus = fork();
- if (forkstatus == -1) /* the fork failed */
- {
- ttyedit ();
- #ifndef HARD_TERMS
- t_init ();
- #endif
- Errcode = ECANTFORK;
- return ERR;
- }
-
- if (forkstatus == 0) /* we're in the child process */
- {
- signal (SIGINT, SIG_DFL);
- signal (SIGQUIT, SIG_DFL);
- #ifdef BSD
- if (strcmp (name, "sh") != 0) /* not /bin/sh */
- signal (SIGTSTP, SIG_DFL);
- else
- signal (SIGTSTP, SIG_IGN);
- #endif
- if (auto_redraw) /* no params; run a shell */
- {
- execl (path, name, 0);
- _exit (RETERR); /* exec failed, notify parent */
- }
- else
- {
- if (expanded) /* echo it */
- printf ("%s\n", new_command);
-
- execl (path, name, "-c", new_command, 0);
- _exit (RETERR);
- }
- }
-
- /* we're in the parent process here */
- save_int = signal (SIGINT, SIG_IGN); /* ignore interrupts */
- save_quit = signal (SIGQUIT, SIG_IGN);
- while (wait (&childstatus) != forkstatus)
- ;
- save_int = signal (SIGINT, save_int); /* catch interupts */
- save_quit = signal (SIGQUIT, save_quit);
- write (1, "\n\n", 2); /* clear out some message space */
- Currow = Nrows - 1;
- Curcol = 0;
- if ((childstatus >> 8) != 0)
- {
- ttyedit ();
- #ifndef HARD_TERMS
- t_init ();
- #endif
- Errcode = ENOSHELL;
- return ERR;
- }
-
- /* this was the old way, so you can compare to what we do now. */
- /*
- /* if (auto_redraw)
- /* {
- /* ttyedit();
- /* restore_screen ();
- /* }
- /* else
- /* remark("Type control-q to rebuild screen");
- */
-
- /* a la vi: */
- if (! auto_redraw)
- {
- int c;
-
- printf ("type return to continue: ");
- while ((c = getchar()) != '\n' && c != EOF)
- ;
- }
-
- ttyedit ();
- #ifndef HARD_TERMS
- t_init ();
- #endif
- restore_screen ();
-
- return OK;
- }
-
- else
- remark ("Not implemented yet");
-
- return OK;
- }
- SHAR_EOF
- fi
- echo shar: "extracting 'misc.c'" '(3118 characters)'
- if test -f 'misc.c'
- then
- echo shar: "will not over-write existing file 'misc.c'"
- else
- cat << \SHAR_EOF > 'misc.c'
- /*
- ** misc.c
- **
- ** lots of miscellanious routines for the screen editor.
- */
-
- #include "se.h"
- #include "extern.h"
-
- /* cprow --- copy from one row to another for append */
-
- cprow (from, to)
- register int from, to;
- {
- register int col;
-
- for (col = 0; col < Ncols; col++)
- load (Screen_image[from][col], to, col);
- }
-
- /* index --- return position of character in string */
-
- int index (str, c)
- register char str[], c;
- {
- register int i;
-
- for (i = 0; str[i] != EOS; i++)
- if (str[i] == c)
- return (i);
- return (-1);
- }
-
- /* strbsr --- binary search stab for an entry equal to str */
-
- int strbsr (stab, tsize, esize, str)
- char *stab, str[];
- int tsize, esize;
- {
- /* stab should have been declared like this:
-
- static struct {
- char *s;
- ...
- } stab[] = {
- "string1", ...
- "string2", ...
- ... ...
- };
-
- The call to strbsr should look like this:
-
- i = strbsr (stab, sizeof (stab), sizeof (stab[0]), str);
- */
-
- register int i, j, k, x;
- int strcmp ();
-
- i = 0;
- j = tsize / esize - 1;
- do {
- k = (i + j) / 2;
- if ((x = strcmp (str, *(char **)(stab + esize * k))) < 0)
- j = k - 1; /* GREATER */
- else if (x == 0)
- return (k); /* EQUAL */
- else
- i = k + 1; /* LESS */
- } while (i <= j);
-
- return (EOF);
- }
-
- /* strmap --- map a string to upper/lower case */
-
- int strmap (str, ul)
- register char str[];
- int ul;
- {
- register int i;
-
- if (isupper (ul))
- for (i = 0; str[i] != '0'; i++)
- str[i] = islower (str[i]) ? toupper (str[i]) : str[i];
- else
- for (i = 0; str[i] == EOS; i++)
- str[i] = isupper (str[i]) ? tolower (str[i]) : str[i];
- return (i);
- }
-
-
- /* xindex --- invert condition returned by index */
-
- int xindex (array, c, allbut, lastto)
- char array[], c;
- int allbut, lastto;
- {
- int index ();
-
- if (c == EOS)
- return (-1);
- if (allbut == NO)
- return (index (array, c));
- if (index (array, c) > -1)
- return (-1);
- return (lastto + 1);
- }
-
-
- /* ctoi --- convert decimal string to a single precision integer */
-
- int ctoi (str, i)
- register char str[];
- register int *i;
- {
- register int ret;
-
- SKIPBL (str, *i);
- for (ret = 0; isdigit (str[*i]); (*i)++)
- ret = ret * 10 + (str[*i] - '0');
- return (ret);
- }
-
-
- /* move_ --- move l bytes from here to there */
-
- move_ (here, there, l)
- register char *here, *there;
- register int l;
- {
- while (l--)
- *there++ = *here++;
- }
-
-
- /* twrite --- stuff characters into the terminal output buffer */
-
- twrite (fd, buf, len)
- register int fd, len;
- register char *buf;
- {
-
- if ((Tobp - Tobuf) + 1 + len > MAXTOBUF)
- tflush ();
-
- if (fd != 1 || len > MAXTOBUF)
- {
- write (fd, buf, len);
- return;
- }
-
- while (len--)
- *++Tobp = *buf++;
- }
-
-
- /* tflush --- clear out the terminal output buffer */
-
- tflush ()
- {
- write (1, Tobuf, (int)(Tobp - Tobuf + 1));
- Tobp = Tobuf - 1;
- }
-
-
-
- /* basename -- return last portion of a pathname */
-
- char *basename (str)
- register char *str;
- {
- register char *cp;
- #ifdef USG
- #define rindex strrchr
- #endif
- char *rindex ();
-
- if ((cp = rindex(str, '/')) == NULL)
- return (str); /* no '/' found, return whole name */
- else
- return (++cp); /* skip over slash to name after it */
- }
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
-
-